package org.atlantis.evnlib;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.atlantis.evnlib.exception.EventException;

class DefaultEventReceiver implements EventReceiver {

	private final Object target;
	private final Method method;

	DefaultEventReceiver(Object target, Method method) {
		this.target = target;
		this.method = method;
		this.method.setAccessible(true);
	}

	@Override
	public void receive(EventArg eventArg) {
		try {
			method.invoke(target, eventArg);
		} catch (IllegalArgumentException e) {
			throw new EventException(e, "Method<%s> rejected argument: %s.", method.getName(), eventArg);
		} catch (IllegalAccessException e) {
			throw new EventException(e, "Method<%s> became inaccessible.", method.getName());
		} catch (InvocationTargetException e) {
			throw new EventException(e, "Method<%s> invoked fail by target<%s>.", method.getName(), target.getClass());
		}
	}

	@Override
	public int hashCode() {
		final int PRIME = 31;
		return (PRIME + method.hashCode()) * PRIME + target.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) return true;
		if (obj == null) return false;
		if (getClass() != obj.getClass()) return false;
		final DefaultEventReceiver other = (DefaultEventReceiver) obj;
		return method.equals(other.method) && target == other.target;
	}

	@Override
	public String toString() {
		return String.format("DefaultEventReceiver<target:%s, method:%s>", target.getClass().getSimpleName(),
				method.getName());
	}
}
